﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MT.CustomUserControl.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;

namespace MT.CustomUserControl.ViewModels
{
    public enum ShowType
    {
        List = 0,
        Book,
    }

    public class PaginationUcViewModel<T>:ObservableObject
    {
        public ShowType ContentShowType = ShowType.List;

        public int MaxLinesInOnePage = 20;

        /// <summary>
        /// 用于显示的所有页的数据
        /// </summary>
        public List<T> AllObjectsToShow = new List<T>();

        /// <summary>
        /// 当前页要显示的数据
        /// </summary>
        private ObservableCollection<T> objectsInCurPagToShow = new ObservableCollection<T>();
        public ObservableCollection<T> ObjectsInCurPagToShow
        {
            get { return objectsInCurPagToShow; }
            set {  SetProperty (ref objectsInCurPagToShow, value); }
        }

        /// <summary>
        /// 当前页改变的Action
        /// </summary>
        public Action<int> CurPageChangedAction;

        /// <summary>
        /// 当前页
        /// </summary>
        private int curPage = 1;
        public int CurPage
        {
            get { return curPage; }
            set 
            {
                if (curPage != value)
                {
                    SetProperty(ref curPage, value);
                    PageSkip = CurPage;
                    UpdatePageInfoByCurPage(curPage);
                }                
            }
        }

        /// <summary>
        /// 记录总数
        /// </summary>
        private int recordTotal;
        public int RecordTotal
        {
            get { return recordTotal; }
            set { SetProperty(ref recordTotal, value); }
        }

        /// <summary>
        /// 页码总数
        /// </summary>
        private int pageTotal;
        public int PageTotal
        {
            get { return pageTotal; }   
            set { SetProperty(ref pageTotal, value); }
        }

        /// <summary>
        /// 页码按钮文本
        /// </summary>
        private ObservableCollection<PageBtnMode> pageBtnContents = new ObservableCollection<PageBtnMode>();
        public ObservableCollection<PageBtnMode> PageBtnContents
        {
            get { return pageBtnContents; }
            set { SetProperty(ref pageBtnContents, value); }
        }

        /// <summary>
        /// 页码按钮是否可见
        /// </summary>
        private Visibility pageBtnsVisibility = Visibility.Visible;
        public Visibility PageBtnsVisibility
        {
            get { return pageBtnsVisibility; }
            set { SetProperty(ref pageBtnsVisibility, value); }
        }

        /// <summary>
        /// 跳转页
        /// </summary>
        private int pageSkip = 1;
        public int PageSkip
        {
            get { return pageSkip; }
            set 
            { 
                SetProperty(ref pageSkip, value);

                if (pageSkip < 1)
                    pageSkip = 1;

                if (pageSkip > PageTotal)
                    pageSkip = PageTotal;
            }
        }

        /// <summary>
        /// 左按钮命令
        /// </summary>
        private RelayCommand<string> pageBtnCommand;
        public RelayCommand<string> PageBtnCommand
        {
            get
            {
                if (pageBtnCommand == null)
                {
                    pageBtnCommand = new RelayCommand<string>(PageBtnCommandFunc);
                }
                return pageBtnCommand;
            }
        }

        /// <summary>
        /// 左按钮命令
        /// </summary>
        private RelayCommand leftBtnCommand;
        public RelayCommand LeftBtnCommand
        {
            get
            {
                if (leftBtnCommand == null)
                {
                    leftBtnCommand = new RelayCommand(LeftBtnCommandFunc);
                }
                return leftBtnCommand;
            }
        }

        /// <summary>
        /// 右按钮命令
        /// </summary>
        private RelayCommand rightBtnCommand;
        public RelayCommand RightBtnCommand
        {
            get
            {
                if (rightBtnCommand == null)
                {
                    rightBtnCommand = new RelayCommand(RightBtnCommandFunc);
                }
                return rightBtnCommand;
            }
        }

        /// <summary>
        /// 跳转命令
        /// </summary>
        private RelayCommand skipCommand;
        public RelayCommand SkipCommand
        {
            get
            {
                if (skipCommand == null)
                {
                    skipCommand = new RelayCommand(SkipCommandFunc);
                }
                return skipCommand;
            }
        }

        public PaginationUcViewModel(int maxLinesInOnePage, ShowType contentShowType = ShowType.List)
        {
            MaxLinesInOnePage = maxLinesInOnePage;
            ContentShowType = contentShowType;
        }

        /// <summary>
        /// 页码按钮命令
        /// </summary>
        /// <param name="skipPage">The skip page.</param>
        private void PageBtnCommandFunc(string page)
        {
            int.TryParse(page, out int temp);
            if (temp != 0 && temp <= PageTotal)
                CurPage = temp;
        }

        /// <summary>
        /// 左按钮命令
        /// </summary>
        /// <param name="skipPage">The skip page.</param>
        private void LeftBtnCommandFunc()
        {
            if(CurPage > 1)
            {
                CurPage--;
                PageSkip = CurPage;
            }                
        }

        /// <summary>
        /// 右按钮命令
        /// </summary>
        /// <param name="skipPage">The skip page.</param>
        private void RightBtnCommandFunc()
        {
            if (CurPage < PageTotal)
            {
                CurPage++;
            }                
        }

        /// <summary>
        /// 跳转命令
        /// </summary>
        /// <param name="skipPage">The skip page.</param>
        private void SkipCommandFunc()
        {
            if (PageSkip != 0)
            {
                CurPage = PageSkip;
                foreach (var item in PageBtnContents)
                {
                    if (item.BtnContentt == CurPage.ToString())
                    {
                        item.BtnIsChecked = true;
                        break;
                    }
                }
            }                
        }

        private void ResetPageInfo()
        {
            PageBtnContents.Clear();
            PageBtnContents.Add(new PageBtnMode("1"));
            PageSkip = 1;
            CurPage = 1;
        }

        /// <summary>
        /// 更新页码条
        /// </summary>
        private void UpdatePageInfoByPageTotal()
        {
            int nPageTotal = AllObjectsToShow.Count / MaxLinesInOnePage;
            if (AllObjectsToShow.Count % MaxLinesInOnePage != 0)
                nPageTotal = nPageTotal + 1;

            PageTotal = nPageTotal;
            ResetPageInfo();

            PageBtnContents.Clear();
            if (PageTotal == 1)
            {
                PageBtnContents.Add(new PageBtnMode("1") { BtnIsChecked=true});
            }
            else if (PageTotal > 1 && PageTotal <= 10)
            {
                PageBtnContents.Add(new PageBtnMode("1") { BtnIsChecked = true });
                for (int i = 1; i < PageTotal; i++)
                {
                    PageBtnContents.Add(new PageBtnMode($"{i + 1}"));
                }              
            }
            else if (PageTotal > 10)
            {
                int centerPage = PageTotal / 2;
                PageBtnContents.Add(new PageBtnMode("1") { BtnIsChecked = true });
                PageBtnContents.Add(new PageBtnMode("..."));
                PageBtnContents.Add(new PageBtnMode($"{centerPage - 2}"));
                PageBtnContents.Add(new PageBtnMode($"{centerPage - 1}"));
                PageBtnContents.Add(new PageBtnMode($"{centerPage}"));
                PageBtnContents.Add(new PageBtnMode($"{centerPage + 1}"));
                PageBtnContents.Add(new PageBtnMode($"{centerPage + 2}"));
                PageBtnContents.Add(new PageBtnMode("..."));
                PageBtnContents.Add(new PageBtnMode($"{PageTotal}"));
            }
        }

        private void UpdatePageInfoByPageTotalInBookType()
        {
            PageBtnContents.Clear();
            if (PageTotal == 1)
            {
                PageBtnContents.Add(new PageBtnMode("1") { BtnIsChecked = true });
            }
            else if (PageTotal > 1 && PageTotal <= 10)
            {
                PageBtnContents.Add(new PageBtnMode("1") { BtnIsChecked = true });
                for (int i = 1; i < PageTotal; i++)
                {
                    PageBtnContents.Add(new PageBtnMode($"{i + 1}"));
                }
            }
            else if (PageTotal > 10)
            {
                int centerPage = PageTotal / 2;
                PageBtnContents.Add(new PageBtnMode("1") { BtnIsChecked = true });
                PageBtnContents.Add(new PageBtnMode("..."));
                PageBtnContents.Add(new PageBtnMode($"{centerPage - 2}"));
                PageBtnContents.Add(new PageBtnMode($"{centerPage - 1}"));
                PageBtnContents.Add(new PageBtnMode($"{centerPage}"));
                PageBtnContents.Add(new PageBtnMode($"{centerPage + 1}"));
                PageBtnContents.Add(new PageBtnMode($"{centerPage + 2}"));
                PageBtnContents.Add(new PageBtnMode("..."));
                PageBtnContents.Add(new PageBtnMode($"{PageTotal}"));
            }
        }

        /// <summary>
        /// 根据当前页更新条码表
        /// </summary>
        /// <param name="curPage"></param>
        private void UpdatePageInfoByCurPage(int curPage)
        {
            foreach (var item in PageBtnContents)
            {
                if (item.BtnContentt == curPage.ToString())
                    item.BtnIsChecked = true;
            }

            if (ContentShowType == ShowType.Book)
            {
                CurPageChangedAction?.Invoke(curPage);
            }
            else
            {
                //更新数据
                ObjectsInCurPagToShow.Clear();
                for (int i = 0; i < MaxLinesInOnePage; i++)
                {
                    int index = MaxLinesInOnePage * (curPage - 1) + i;
                    if (index < AllObjectsToShow.Count)
                        ObjectsInCurPagToShow.Add(AllObjectsToShow[index]);
                    else
                        break;
                }

                //更新UI上的按钮
                var temp = PageBtnContents.Where(p => p.BtnContentt == curPage.ToString()).ToList();
                if (temp.Count() == 1)
                {
                    PageBtnMode pageBtnMod = temp[0];
                    pageBtnMod.BtnIsChecked = true;
                }
                else
                {
                    if (curPage > 10 && curPage < PageTotal - 2)
                    {
                        PageBtnContents.Clear();
                        PageBtnContents.Add(new PageBtnMode("1"));
                        PageBtnContents.Add(new PageBtnMode("..."));
                        PageBtnContents.Add(new PageBtnMode($"{curPage - 2}"));
                        PageBtnContents.Add(new PageBtnMode($"{curPage - 1}"));
                        PageBtnContents.Add(new PageBtnMode($"{curPage}") { BtnIsChecked = true });
                        PageBtnContents.Add(new PageBtnMode($"{curPage + 1}"));
                        PageBtnContents.Add(new PageBtnMode($"{curPage + 2}"));
                        PageBtnContents.Add(new PageBtnMode("..."));
                        PageBtnContents.Add(new PageBtnMode($"{PageTotal}"));
                    }
                }
            }
        }

        public void UpdatePageInfoByChange(List<T> allObjectsToShow, ObservableCollection<T> onePagObjectsToShow)
        {
            AllObjectsToShow = allObjectsToShow;
            ObjectsInCurPagToShow = onePagObjectsToShow;
            UpdatePageInfoByPageTotal();
            UpdatePageInfoByCurPage(1);
        }

        /// <summary>
        /// 更新页码总数，有两种类型，一种是应用在列表上，一种是应用在书籍上
        /// </summary>
        /// <param name="nPageTotal"></param>
        /// <param name="isBookType">显示内容是否为书籍类型</param>
        public void UpdatePageTotal(int nPageTotal)
        {
            PageTotal = nPageTotal;
            ResetPageInfo();

            if (ContentShowType == ShowType.Book)
                UpdatePageInfoByPageTotalInBookType();
            else
                UpdatePageInfoByPageTotal();
        }

        /// <summary>
        /// 更新记录总数
        /// </summary>
        public void UpdateRecordTotal(int total)        
        {
            RecordTotal = total;
        }
    }
}
